package com.yiqi.zhiyuan.feature.order.view;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Poi;
import com.amap.api.navi.AmapNaviPage;
import com.amap.api.navi.AmapNaviParams;
import com.amap.api.navi.AmapNaviType;
import com.suozhang.framework.component.websocket.WsManager;
import com.suozhang.framework.entity.bo.Result;
import com.suozhang.framework.framework.AM;
import com.suozhang.framework.framework.BaseActivity;
import com.suozhang.framework.utils.LocationUtils;
import com.suozhang.framework.utils.logger.Logger;
import com.suozhang.framework.widget.dialog.NormalDialog;
import com.suozhang.framework.widget.dialog.OnBtnClickL;
import com.yiqi.zhiyuan.R;
import com.yiqi.zhiyuan.common.map.AMapUtil;
import com.yiqi.zhiyuan.common.utils.AppUtil;
import com.yiqi.zhiyuan.entity.vo.EndPushVO;
import com.yiqi.zhiyuan.entity.vo.OrderVO;
import com.yiqi.zhiyuan.feature.order.contract.OrderInfoContract;
import com.yiqi.zhiyuan.feature.order.dependencies.info.DaggerOrderInfoComponent;
import com.yiqi.zhiyuan.feature.order.dependencies.info.OrderInfoPresenterModule;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

import static com.suozhang.framework.component.websocket.WSHost.WSURL_ORDER;
import static com.yiqi.zhiyuan.common.utils.AppUtil.formatDouble;

public class EndTaskActivity extends BaseActivity implements OrderInfoContract.View {

    @BindView(R.id.toolbar)
    Toolbar mToolbar;
    @BindView(R.id.tv_order_end_departure)
    TextView mTvOrderEndDeparture;
    @BindView(R.id.tv_order_end_destination)
    TextView mTvOrderEndDestination;
    @BindView(R.id.tv_order_driving_time)
    TextView mTvOrderDrivingTime;
    @BindView(R.id.tv_order_driving_kile)
    TextView mTvOrderDrivingKile;
    @BindView(R.id.tv_order_starting_score)
    TextView mTvOrderStartingScore;
    @BindView(R.id.tv_order_kile_score)
    TextView mTvOrderKileScore;
    @BindView(R.id.tv_order_time_score)
    TextView mTvOrderTimeScore;
    @BindView(R.id.tv_order_total_score)
    TextView mTvOrderTotalScore;
    @BindView(R.id.tv_show_loc)
    TextView mTvShowLoc;
    @BindView(R.id.tv_card_order_waypoint1)
    TextView mTvCardOrderWaypoint1;
    @BindView(R.id.tv_card_order_waypoint2)
    TextView mTvCardOrderWaypoint2;

    private WebSocket mSocket;
    private final String TAG = getClass().getSimpleName();
    private OrderVO mOrderVO;
    private static final int COMPLETED = 1;

    private CompositeDisposable mCompositeDisposable = new CompositeDisposable();


    @Inject
    OrderInfoContract.Presenter mPresenter;

    private WsManager mWsManager;

    private boolean isLocationSuccess = false;


    @Override
    protected int attachLayoutRes() {
        return R.layout.activity_end_task;
    }

    @Override
    protected void initView() {
        mTvShowLoc.setVisibility(View.GONE);
        initToolBar(mToolbar, "服务中", true, true);
        mOrderVO = (OrderVO) this.getIntent().getSerializableExtra("order_info");
        if (mOrderVO != null) {
            mTvOrderEndDeparture.setText(mOrderVO.getDeparture());
            mTvOrderEndDestination.setText(mOrderVO.getDestination());
            mTvCardOrderWaypoint1.setVisibility(TextUtils.isEmpty(mOrderVO.getWaypoint1()) ? View.GONE : View.VISIBLE);
            mTvCardOrderWaypoint2.setVisibility(TextUtils.isEmpty(mOrderVO.getWaypoint2()) ? View.GONE : View.VISIBLE);
            mTvCardOrderWaypoint1.setText(TextUtils.isEmpty(mOrderVO.getWaypoint1()) ? "" : "途径点：" + mOrderVO.getWaypoint1());
            mTvCardOrderWaypoint2.setText(TextUtils.isEmpty(mOrderVO.getWaypoint2()) ? "" : "途径点：" + mOrderVO.getWaypoint2());
        }
    }

    @Override
    protected void initInjector() {
        DaggerOrderInfoComponent.builder().orderInfoPresenterModule(new OrderInfoPresenterModule(this)).build().inject(this);
    }


    @Override
    protected void getMessage(String msg) {
        showMsg(msg);
    }

    @Override
    protected void initData() {

        initLocation();
        start();
    }

    @Override
    protected void initEvent() {
        if (!LocationUtils.isGpsEnabled()) {
            initGpsDialog();
        }
    }

    @OnClick(R.id.btn_order_end)
    public void onViewClicked() {
        if (mOrderVO != null) {
            mPresenter.endTask(mOrderVO.getOrderNo(), mOrderVO.getUseCarType());
        }

    }

    @Override
    public void showEndTaskSuccess(EndPushVO endPushVO) {
        Intent intent = new Intent(this, ScheduleConfirmedActivity.class);
        intent.putExtra("order_info", mOrderVO);
        intent.putExtra("end_data", endPushVO);
        startActivity(intent);
        finish();
    }

    @Override
    public void showEndTaskError(String errorMsg) {
        showMsg(errorMsg);
    }

    @Override
    public void showStartTaskSuccess() {

    }

    @Override
    public void showStartTaskError(String errorMsg) {

    }

    @Override
    public void showOrderDetailSuccess(OrderVO data) {

    }

    @Override
    public void showOrderDetailError(String errorMsg) {
//      T.sho
    }

    @Override
    public void showArriveAtLocationSuccess() {

    }

    @Override
    public void showPassengersGettingOnBusSuccess() {

    }

    @Override
    public void showGoNowSuccess() {

    }

    @Override
    public void showComfirmTripSuccess() {

    }


    @OnClick(R.id.btn_order_passengers)
    public void onViewPassengersClicked() {
        if (mOrderVO == null) return;
        if (LocationUtils.isGpsEnabled()) {
            List<Poi> wayList = AMapUtil.convertPoiList(mOrderVO);//途径点目前最多支持3个。
            Poi start = new Poi(mOrderVO.getDeparture(), new LatLng(mOrderVO.getDepLatitude(), mOrderVO.getDepLongitude()), "");
            Poi end = new Poi(mOrderVO.getDestination(), new LatLng(mOrderVO.getDesLatitude(), mOrderVO.getDesLongitude()), "");
            AmapNaviPage.getInstance().showRouteActivity(this, new AmapNaviParams(start, wayList, end, AmapNaviType.DRIVER), null);
        } else {
            initGpsDialog();
        }
    }


    private void initGpsDialog() {
        NormalDialog dialog = new NormalDialog(this);
        dialog.content("导航需要GPS，请先打开GPS");
        dialog.isTitleShow(false);
        dialog.btnNum(2);
        dialog.setOnBtnClickL(new OnBtnClickL() {
            @Override
            public void onBtnClick() {
                dialog.dismiss();
            }
        }, new OnBtnClickL() {
            @Override
            public void onBtnClick() {
                dialog.dismiss();
                LocationUtils.openGpsSettings();
            }
        });
        dialog.show();
    }

    private void start() {
        OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
                .readTimeout(3, TimeUnit.SECONDS)//设置读取超时时间
                .writeTimeout(3, TimeUnit.SECONDS)//设置写的超时时间
                .connectTimeout(3, TimeUnit.SECONDS)//设置连接超时时间
                .build();

        Request request = new Request.Builder().url(WSURL_ORDER).build();
        EchoWebSocketListener socketListener = new EchoWebSocketListener();
        mOkHttpClient.newWebSocket(request, socketListener);
        mOkHttpClient.dispatcher().executorService().shutdown();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // TODO: add setContentView(...) invocation
        ButterKnife.bind(this);
    }


    private final class EchoWebSocketListener extends WebSocketListener {

        @Override
        public void onOpen(WebSocket webSocket, Response response) {
            super.onOpen(webSocket, response);
            mSocket = webSocket;
//            //连接成功后，发送登录信息
            Map<String, Object> map = new HashMap<>();
            map.put("driverId", AM.user().getLoginResultCache().getId());
            map.put("orderNo", mOrderVO.getOrderNo());
            String message = JSON.toJSONString(map);
            mSocket.send(message);
            output("连接成功！");
            test();
        }

        @Override
        public void onMessage(WebSocket webSocket, ByteString bytes) {
            super.onMessage(webSocket, bytes);
            output("receive bytes:" + bytes.hex());
        }

        @Override
        public void onMessage(WebSocket webSocket, String text) {
            super.onMessage(webSocket, text);
            output("receive text:" + text);
            Result<EndPushVO> result = JSONObject.parseObject(text, new TypeReference<Result<EndPushVO>>() {
            });
            if (result != null && result.getData() != null) {
                handler.sendMessage(handler.obtainMessage(COMPLETED, result.getData()));
            }

        }

        @Override
        public void onClosed(WebSocket webSocket, int code, String reason) {
            super.onClosed(webSocket, code, reason);
            output("closed:" + reason);
        }

        @Override
        public void onClosing(WebSocket webSocket, int code, String reason) {
            super.onClosing(webSocket, code, reason);
            output("closing:" + reason);
        }

        @Override
        public void onFailure(WebSocket webSocket, Throwable t, Response response) {
            super.onFailure(webSocket, t, response);
            output("发送失败---》:" + t.getMessage());
        }
    }

    private void output(final String text) {
//        showMsg(text);
        Logger.e(text);
    }


    /**
     * 接收解析后传过来的数据
     */
    @SuppressLint("HandlerLeak")
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            EndPushVO model = (EndPushVO) msg.obj;
            if (model != null) {
                mTvOrderDrivingTime.setText(AppUtil.secToTime(model.getDrivingTime()));
                mTvOrderDrivingKile.setText(formatDouble(model.getDrivingKile()));
                mTvOrderStartingScore.setText(formatDouble(model.getStartingPrice()) + "积分");
                mTvOrderKileScore.setText(formatDouble(model.getKilePrice()) + "积分");
                mTvOrderTimeScore.setText(formatDouble(model.getDrivingPrice()) + "积分");
                mTvOrderTotalScore.setText(formatDouble(model.getTotal()) + "积分");
            }
        }
    };

    @Override
    protected void onStop() {
        super.onStop();


    }


    public synchronized void closeWebSocket() {
        if (mSocket != null) {
            if (!AM.user().isLogin()) return;
            //连接成功后，发送登录信息
            Map<String, Object> map = new HashMap<>();
            map.put("driverId", AM.user().getLoginResultCache().getId());
            map.put("isCloss", 1);
            String message = JSON.toJSONString(map);
            mSocket.send(message);
            mSocket.close(1001, "byebye");
            mSocket = null;
        }
    }

    private AMapLocationClient mLocationClient;
    private AMapLocation mAMapLocation;

    //    AmapRouteActivity
    private void initLocation() {
        mLocationClient = new AMapLocationClient(this);
        AMapLocationClientOption option = new AMapLocationClientOption();
        option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //设置定位间隔,单位毫秒,默认为2000ms
        option.setInterval(5000);
        mLocationClient.setLocationOption(option);
        mLocationClient.setLocationListener(new AMapLocationListener() {
            @Override
            public void onLocationChanged(AMapLocation amapLocation) {
                Logger.d("AMapLocationClient-----onLocationChanged---->");
                if (amapLocation != null) {
                    if (amapLocation.getErrorCode() == 0) {
                        mAMapLocation = amapLocation;
//                        sendHeart();
                    }
                } else {
                    //显示错误信息ErrCode是错误码，errInfo是错误信息，详见错误码表。
                    showMsg("location Error, ErrCode:"
                            + amapLocation.getErrorCode() + ", errInfo:"
                            + amapLocation.getErrorInfo());
                }
            }

        });
        mLocationClient.startLocation();
    }


    private void sendHeart() {

        if (!AM.user().isLogin()) return;
        //连接成功后，发送心跳包
        Map<String, Object> mapStr = new HashMap<>();
        mapStr.put("driverId", AM.user().getLoginResultCache().getId());
        mapStr.put("orderNo", mOrderVO.getOrderNo());
        if (mAMapLocation != null) {
            mapStr.put("lat", mAMapLocation.getLatitude());
            mapStr.put("lng", mAMapLocation.getLongitude());
        }
        String messageStr = JSON.toJSONString(mapStr);
        if (mSocket != null) {
            mSocket.send(messageStr);
            Logger.d("行程中心跳包---》" + messageStr);
//            mTvShowLoc.setText(mapStr.get("lat")+"\n" +mapStr.get("lng"));
        }
    }

    private void test() {
        mCompositeDisposable.add(Observable.interval(0, 5, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(getObserver(1)));
    }

    private DisposableObserver getObserver(final int id) {
        DisposableObserver disposableObserver = new DisposableObserver<Object>() {
            @Override
            public void onNext(Object o) {
                sendHeart();
            }

            @Override
            public void onComplete() {

            }

            @Override
            public void onError(Throwable e) {
                Log.e(id + TAG, e.toString(), e);
            }
        };

        return disposableObserver;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 如果退出程序，就清除后台任务
        if (mLocationClient != null) {
            mLocationClient.stopLocation();
            mLocationClient.onDestroy();
            mLocationClient = null;
        }
        if (mCompositeDisposable != null) {
            mCompositeDisposable.clear();
            mCompositeDisposable = null;
        }

        closeWebSocket();
    }
}
